package simple_bbs.endpoint;

import act.aaa.LoginUser;
import act.app.ActionContext;
import act.controller.Controller;
import act.db.DbBind;
import act.inject.DefaultValue;
import org.osgl.aaa.AAA;
import org.osgl.aaa.NoAuthentication;
import org.osgl.mvc.annotation.DeleteAction;
import org.osgl.mvc.annotation.GetAction;
import org.osgl.mvc.annotation.PostAction;
import simple_bbs.model.Message;
import simple_bbs.model.User;
import simple_bbs.security.AppSecurity;

import javax.inject.Inject;
import javax.validation.Valid;

/**
 * User must be authorized to access resources exposed by this endpoint
 */
public class BBSController extends Controller.Util {

    @LoginUser
    private User me;

    @Inject
    public Message.Dao dao;

    /**
     * Show the current login user's profile
     * @return the current login user
     */
    @GetAction("/me")
    public User myProfile() {
        return me;
    }

    /**
     * List messages specified by page
     * @param page the page number
     */
    @GetAction("/message")
    @NoAuthentication
    public void listMessages(@DefaultValue("0") int page) {
        Iterable<Message> list = dao.fetch(page);
        double max = (double)dao.count() / 20.0 - 1.0;
        max = Math.ceil(max);
        render(list, max);
    }

    /**
     * Show message detail page
     * @param message the message (bound to URL path variable)
     * @param dao the user dao
     */
    @GetAction("/message/{message}")
    @NoAuthentication
    public void read(@DbBind Message message, User.Dao dao) {
        notFoundIfNull(message);
        User author = dao.findByEmail(message.author);
        if (null == author) {
            author = User.ANONYMOUS;
        }
        render("view.html", message, author);
    }


    /**
     * Load the message form
     * @param message the message to edit, when not provided then create new message
     */
    @GetAction("/form/{message}")
    public void form(@DbBind Message message) {
        render("form.html", message);
    }

    /**
     * Create/Update message
     * @param message the message data resolved from http request
     * @param context the current HTTP request action context
     */
    @PostAction("/form")
    public void create(@Valid Message message, ActionContext context) {
        if (null == message.getIdAsStr()) {
            message.author = me.email;
            AAA.requirePermission(message, AppSecurity.PERM_CREATE);
        } else {
            Message existingMessage = dao.findById(message.getIdAsStr());
            notFoundIfNull(existingMessage);
            message.author = existingMessage.author;
            AAA.requirePermission(message, AppSecurity.PERM_UPDATE);
        }
        if (context.hasViolation()) {
            render("form.html", message);
        }
        dao.save(message);
        redirect("/");
    }

    /**
     * Delete a message by ID
     * @param message the Message object resolved from URL path variable
     */
    @DeleteAction("/message/{message}")
    public void delete(@DbBind Message message) {
        notFoundIfNull(message);
        AAA.requirePermission(message, AppSecurity.PERM_DELETE);
        dao.delete(message);
    }

}
